home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / daymisckit_proj / daymisckit-1 / DAYLockFile.m < prev    next >
Text File  |  1995-06-12  |  4KB  |  134 lines

  1. //
  2. //    DAYLockFile.h -- a generic class to simplify keeping an atomic lock file
  3. //        Written by Don Yacktman (c) 1993 by Don Yacktman.
  4. //                Version 1.0.  All rights reserved.
  5. //
  6. //        This is a free object!  Contact the author for the latest version.
  7. //        Don Yacktman, 4279 N. Ivy Lane, Provo, UT, 84604
  8. //        e-mail:  Don_Yacktman@byu.edu
  9. //
  10. //        You may use and copy this class freely as long as you
  11. //        comply with the following terms:
  12. //            (1) Do not remove the author's name or any of the
  13. //                copyright notices from this file.
  14. //            (2) If you redistribute an application which uses this
  15. //                object, you must either include the source code for
  16. //                this object with the application or state in your
  17. //                application's documentation that you (a) use this
  18. //                object and (b) where to obtain the source code for
  19. //                the object.
  20. //            (3) In no way shall the author or his employer(s) be held
  21. //                responsible for any damages caused by what this object
  22. //                does or does not do.
  23. //            (4) You have no warranty whatsoever that this object is
  24. //                good for any purpose at all.  If you find it useful
  25. //                for something, consider yourself lucky and leave it at that.
  26. //
  27.  
  28. #import <daymisckit/daymisckit.h>
  29. #import <sys/file.h>
  30. #import <sys/vnode.h>
  31.  
  32. @implementation DAYLockFile
  33.  
  34. - init
  35. {
  36.     id ret = [super init];
  37.     haveLock = NO;
  38.     return ret;
  39. }
  40.  
  41. - fileName { return lockFileName; }
  42. - setFileName:aString
  43. {
  44.     if (haveLock) [self unlock];
  45.     lockFileName = aString;
  46.     return self;
  47. }
  48.  
  49. - lock  // atomically create a lock file.  returns YES on success
  50. {    // lock file contains the PID of the locking process.
  51.     int lockFileFD; char buffer[16];
  52.     if (!lockFileName || ![lockFileName stringValue])
  53.         return self; // always "have" lock if no lock file used
  54.     if (haveLock) return self; // already been done
  55.     lockFileFD = open([lockFileName stringValue],    // file name
  56.             (O_EXCL | O_CREAT | O_RDWR),    // error if exists; create if doesn't
  57.             (VREAD | VWRITE)); // mode is owner r/w
  58.     if (lockFileFD < 0) return nil; // error opening the lock file
  59.     sprintf(buffer, "%d", getpid());
  60.     if (write(lockFileFD, buffer, strlen(buffer)) < 0) return nil; // couldn't write
  61.     if (close(lockFileFD)) return nil; // error closing the lock file
  62.     haveLock = YES;
  63.     return self;
  64. }
  65.  
  66. - unlock    // remove the lock file.
  67. {
  68.     if (!lockFileName || ![lockFileName stringValue])
  69.         return self; // always "had" lock if no lock file used
  70.     if (!haveLock) return nil;
  71.     if (unlink([lockFileName stringValue])) return nil;  // error in unlink()
  72.     haveLock = NO; // the lock was successfully removed.
  73.     return self;
  74. }
  75.  
  76. - (BOOL)haveLock { return (haveLock || !lockFileName); }
  77.  
  78. - copy
  79. {    // copies do not have locks or open logs... only original can!
  80.     id myCopy = [[DAYLockFile alloc] init];
  81.     [myCopy setFileName:lockFileName];
  82.     return myCopy;
  83. }
  84.  
  85. - read:(NXTypedStream *)stream
  86. {
  87.     [super read:stream];
  88.     lockFileName = NXReadObject(stream);
  89.     haveLock = NO;
  90.     return self;
  91. }
  92.  
  93. - write:(NXTypedStream *)stream
  94. {
  95.     [super write:stream];
  96.     NXWriteObject(stream, lockFileName);
  97.     return self;
  98. }
  99.  
  100. // NXTransport protocol implementation:
  101. - encodeUsing:(id <NXEncoding>)portal
  102. {
  103.     [portal encodeObjectBycopy:lockFileName];
  104.     return self;
  105. }
  106.  
  107. - decodeUsing:(id <NXDecoding>)portal
  108. {
  109.     lockFileName = [portal decodeObject];
  110.     return self;
  111. }
  112.  
  113. - encodeRemotelyFor:(NXConnection *)connection
  114.     freeAfterEncoding:(BOOL *)flagp isBycopy:(BOOL)isByCopy
  115. {
  116.     if (isByCopy) {
  117.         *flagp = NO; // object will copy.
  118.         return self; //encode object (copy it)
  119.     }
  120.     *flagp = NO; // object will copy.
  121.     // super will encode the proxy otherwise
  122.     return [super encodeRemotelyFor:connection
  123.                 freeAfterEncoding:flagp isBycopy:isByCopy];
  124. }
  125.  
  126. - free
  127. {
  128.     if (haveLock) [self unlock];
  129.     [lockFileName free];
  130.     return [super free];
  131. }
  132.  
  133. @end
  134.